Skip to content

allow plugin to work in rolldown #1616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

radnan
Copy link

@radnan radnan commented Jun 18, 2025

rolldown does not expose importedIdResolutions similar to rollup and so we need to move the emit to the render phase

this is the output when using rollup:

image

currently tying to use rolldown gives the following error:

image

but with this patched version we are able to successfully run the plugin in rolldown:

image

Copy link

changeset-bot bot commented Jun 18, 2025

🦋 Changeset detected

Latest commit: d385965

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@vanilla-extract/rollup-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@drwpow
Copy link
Contributor

drwpow commented Jun 23, 2025

(not a maintainer, just interested in Vanilla Extract + Rollup support) This seems like a reasonable change, especially since it seems this is an intentional API departure on Rolldown’s end.

Would you be able to add a Rolldown test to ensure this a) works as intended and b) doesn’t regress? (again, not a maintainer, just also interested in this fix)

@@ -75,4 +79,76 @@ describe('rollup-plugin', () => {
]),
).toMatchSnapshot();
});

describe('should be compatible with rolldown', () => {
Copy link
Author

@radnan radnan Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added unit tests for rolldown @drwpow - thanks for the suggestion!

@askoufis
Copy link
Contributor

@radnan I just merged #1604 which introduced conflicts into your branch. I'm happy to take over this PR if you don't have bandwidth the work on it, but if you're happy to keep working on it I'll take a look once the branch is in order.

radnan added 3 commits July 14, 2025 10:58
to preserve `this` context within the object methods
rolldown does not expose importedIdResolutions similar to rollup and so we need
to move the emit to the render phase
const { importedIdResolutions } = getModuleInfo(id) ?? {};
for (const resolution of importedIdResolutions ?? []) {
if (resolution.meta.css && !extractedCssIds.has(resolution.id)) {
const { importedIds } = plugin.getModuleInfo(id) ?? {};
Copy link
Author

@radnan radnan Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for offering to take it up @askoufis! but i resolved the conflicts - didn't look like there were too many of them.

i also duplicated the same extract test under rolldown describe section

and thanks again for taking the time to review this

],
[
"app.js",
"import "./styles/reset.css.js";
Copy link
Contributor

@askoufis askoufis Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like rolldown isn't stripping side-effect imports for some reason.

Here's the equivalent section of the rollup snapshot in master:

.utility_mt400__1vyatv83 {
margin-top: var(--size-space-400);
}",
],
[
"app.js",
"export { default as Button } from './button/button.js';
export { default as Checkbox } from './checkbox/checkbox.js';
export { default as Radio } from './radio/radio.js';

Any thoughts @drwpow?

Copy link
Contributor

@drwpow drwpow Jul 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm yeah we go in and remove those after-the-fact if someone is extracting .css. That happens here, in generateCssBundle():

  for (const id of getModuleIds()) {
    if (cssFileFilter.test(id)) {
      cssFiles[id] = buildImportChain(id, { getModuleInfo, warn });
    }
  }

Ultimately, if they get added to that cssFiles mapping, then we’ll strip the side effect imports later.

I haven’t debugged locally, but what is likely happening is Rolldown doesn’t have a complete graph of this.getModuleIds() at this point in time, so we don’t know that these are side-effects we generated (we obviously don’t touch user code as that would be Bad; we only will remove imports we know Vanilla Extract generated).

If, say, we debugged what the current status is of this.getModuleIds() at this point in time:

+   console.log(getModuleIds());
    for (const id of getModuleIds()) {

I’d expect to see that for whatever reason, Rollup and Rolldown are returning different things here.

If so, maybe it’s because Rolldown hasn’t yet built this graph, or it’s possibly partial, or something. All that tracks, because Rolldown has intentionally departed from some of Rollup’s API which led to this PR in the first place. I may not be able to take a look this week, but it could be as simple as calling generateCssBundle() at some other point in time, maybe.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I remember the file output is not exactly the same in rolldown as it is in rollup

So the file we're looking for might just have been renamed or something internally by rolldown

I guess the strategy to get extractedCssIds has to be looked at

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! Yeah if that’s the case then we can just expand our RegEx to look for both Rollup and Rolldown versions. That still should be pretty safe/I wouldn’t imagine any user code getting accidentally stripped from it (we have multiple checks to ensure we’re not just deleting user code, that’s only one layer).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok so i see what's going on - we're stripping side effects manually - and previously in rollup it was kinda collapsing the modules where needed whereas in rolldown it's not doing that anymore

so rollup produces something like this:

- app.js
- reset.css

and app.js imports reset.css directly removing the interim reset.css.ts file since i guess rollup sees that the interm js file is not needed as it's just side-effects and doesn't export any actual js modules

whereas in rolldown we have:

- app.js
- reset.js
  - reset.css 

app.js is importing reset.js (which was reset.css.ts) and that in turn is importing reset.css. the side effects is now getting stripped from reset.js as you can see here:

https://github.com/radnan/vanilla-extract/blob/d385965a8057dff0ba8ecc9b8fe1de8e780db267/packages/rollup-plugin/test/__snapshots__/rollup-plugin.test.ts.snap#L1578-L1581

but we're left with an empty reset.js file that does nothing. i guess we'd have to do a second pass to manually remove these empty js modules - or just live with it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good find. Yeah I wonder given Rolldown’s current state and active iteration, if we just leave it as-is because I would strongly imagine others run into this, and this gets fixed on Rolldown’s side? Maybe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants